<template>
	<view class="com-image position-relative" :class="{'y-flex': mode != 'widthFix'}" @tap="handleTap">
		<image :lazy-load="lazyLoad" referrer-policy="no-referrer" @load="handleLoad" @error="handleError"
		class="com-image-item trans-background-color trans-border-radius trans-opacity trans-300" :src="url" :mode="mode"
		:style="[imageStyle]"></image>
		<view class="position-absolute-cover trans-background-color trans-border-radius trans-opacity trans-300 y-flex y-align-center y-justify-center" :style="[imageBoxStyle]">
			<slot name="loading" v-if="loading">
				<com-icon name="countdown" :size="tipSize + 10" :color="tipColorSync"></com-icon>
			</slot>
			<slot name="error" v-if="error">
				<view class="y-flex y-row y-align-center" v-if="enableRefresh" @tap.stop="refresh">
					<com-icon name="refresh" :size="tipSize + 10" :color="tipColorSync"></com-icon>
					<text class="ml-10" :style="{color: tipColorSync, 'font-size': pixelunit(tipSize)}">点击刷新</text>
				</view>
				<com-icon name="warn" :size="tipSize + 10" :color="tipColorSync" v-else></com-icon>
			</slot>
		</view>
		<view class="preview-btn y-flex y-align-center y-justify-center position-absolute bottom-10 right-10 opac-7"
		:style="{'background-color': skinColor.color_gap_1}" v-if="showPreviewBtn && !error && !loading" @tap.stop="preview">
			<com-icon name="attention_fill" :color="tipColorSync"></com-icon>
		</view>
	</view>
</template>

<script>
	import SkinColor from '@/assets/skin/index.js'
	import { pixelunit } from '@/assets/js/util.js'
	export default {
		props: {
			//图片链接
			src: {
				type: String,
				default: ''
			},
			//裁剪模式
			mode: {
				type: String,
				default: ''
			},
			//懒加载
			lazyLoad: {
				type: Boolean,
				default: false
			},
			//背景色
			bgColor: {
				type: String,
				default: ''
			},
			//圆角大小
			borderRadius: {
				type: [Number,String],
				default: 0
			},
			borderTopLeftRadius: {
				type: [Number,String],
				default: 0
			},
			borderTopRightRadius: {
				type: [Number,String],
				default: 0
			},
			borderBottomRightRadius: {
				type: [Number,String],
				default: 0
			},
			borderBottomLeftRadius: {
				type: [Number,String],
				default: 0
			},
			//提示文字大小
			tipSize: {
				type: [String, Number],
				default: 30
			},
			//提示文字颜色
			tipColor: {
				type: String,
				default: ''
			},
			//来源
			referer: {
				type: String,
				default: ''
			},
			//开启点击预览功能
			enablePreview: {
				type: Boolean,
				default: false
			},
			//显示预览按钮
			showPreviewBtn: {
				type: Boolean,
				default: false
			},
			//开启错误刷新按钮
			enableRefresh: {
				type: Boolean,
				default: false
			}
		},
		computed: {
			skinMode () {
				return this.$store.getters['setting/GET_SKIN_MODE']
			},
			skinColor () {
				return SkinColor[this.skinMode]
			},
			tipColorSync () {
				return this.tipColor || this.skinColor.color_1
			},
			pixelunit () {
				return pixelunit
			},
			imageStyle () {
				return Object.assign({}, {
					'flex': this.mode != 'widthFix' ? 1 : 0,
					'opacity': (this.loading || this.error) ? 0 : 1
				}, this.mode == 'aspectFit' ? {
					'background-color': this.bgColor || this.skinColor.color_gap_1
				} : this.borderRadiusStyle)
			},
			imageBoxStyle () {
				return Object.assign({}, this.borderRadiusStyle, {
					'background-color': this.bgColor || this.skinColor.color_gap_1,
					'opacity': (this.loading || this.error) ? 1 : 0
				}) 
			},
			borderRadiusStyle () {
				return {
					borderTopLeftRadius: pixelunit(this.borderTopLeftRadius || this.borderRadius),
					borderTopRightRadius: pixelunit(this.borderTopRightRadius || this.borderRadius),
					borderBottomRightRadius: pixelunit(this.borderBottomRightRadius || this.borderRadius),
					borderBottomLeftRadius: pixelunit(this.borderBottomLeftRadius || this.borderRadius),
				}
			}
		},
		data() {
			return {
				loading: true,
				error: false,
				url: ''
			}
		},
		created() {
			this.url = this.src
		},
		methods: {
			handleLoad(e) {
				this.$emit('load', e)
				this.loading = false
			},
			handleError(e) {
				this.error = true
				this.loading = false
				this.$emit('error', e);
			},
			handleTap (e) {
				if ( !this.enablePreview || !this.url || this.error || this.loading ) return
				this.preview(e)
			},
			preview (e) {
				e.stopPropagation && e.stopPropagation()
				uni.previewImage({ urls: [this.url] })
			},
			refresh (e) {
				e.stopPropagation && e.stopPropagation()
				this.url = ''
				this.$nextTick(() => {
					this.url = this.src
					this.loading = true
					this.errorTime = 0
					this.error = false
					this.isCache = false
				})
			}
		},
		watch: {
			src (newVal) {
				this.loading = true
				this.error = false
				this.url = newVal
			}
		}
	}
</script>

<style>
	/* #ifndef APP-NVUE */
	.com-image-item {
		width: 100%;
		flex-shrink: 0;
	}
	/deep/ .com-image-item > div {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
	}
	/* #endif */
	.com-image .preview-btn {
		width: 40rpx;
		height: 40rpx;
		border-radius: 40rpx;
	}
</style>
